package factory;

import java.util.HashMap;
import java.util.Map;

import loadsave.LoadSaveable;
import loadsave.Memento;
import loadsave.loadsaveobject.Iterator;
import loadsave.loadsaveobject.LoadSaveMapComposite;
import loadsave.loadsaveobject.LoadSaveObject;
import loadsave.loadsaveobject.LoadSaveObjectComposite;
import loadsave.loadsaveobject.LoadSavePrimitive;
import effects.CombatEffect;
import effects.DamageEffect;
import effects.Effect;
import effects.GainExperienceEffect;
import effects.HealEffect;
import effects.InstantDeathEffect;
import effects.RiverEffect;
import effects.TeleportEffect;

public class EffectFactory implements LoadSaveable {
	private static Map<String, Effect> effectLibrary = new HashMap<String, Effect>();

	/**
	 * add an Effect to the map
	 * @param toAdd
	 */
	public static void addEffect(Effect toAdd) {
		effectLibrary.put(toAdd.getName(), toAdd);
	}
	
	@Override
	public Memento getMemento() {
		return new Memento() {
			
			@Override
			public LoadSaveObject getState() {
				LoadSaveObjectComposite toReturn = new LoadSaveObjectComposite("effectFactory", "EffectFactory");
				LoadSaveMapComposite lsmc = new LoadSaveMapComposite("effectLibrary", "HashMap", "String", "Effect");
				for (String s : effectLibrary.keySet()) {
					lsmc.add(new LoadSavePrimitive("", "", s), effectLibrary.get(s).getMemento().getState());
				}
				toReturn.add(lsmc.getName(), lsmc);
				return toReturn;
			}

			@Override
			public void restoreState(LoadSaveObject lso) {
				Iterator<LoadSaveObject> iter = lso.get("effectLibrary").getIterator();
				Map<String, Effect> effectTypes = new HashMap<String, Effect>();
				//Wish we could've used reflection here
				effectTypes.put("CombatEffect", new CombatEffect());
				effectTypes.put("DamageEffect", new DamageEffect());
				effectTypes.put("GainExperienceEffect", new GainExperienceEffect());
				effectTypes.put("HealEffect", new HealEffect());
				effectTypes.put("InstantDeathEffect", new InstantDeathEffect());
				effectTypes.put("TeleportEffect", new TeleportEffect());
				effectTypes.put("RiverEffect", new RiverEffect());
				for (iter.init(); iter.hasNext(); iter.next()) {
					effectLibrary.put(iter.getCurrKey().getValue(), effectTypes.get(iter.getCurrVal().getType()).clone());
					effectLibrary.get(iter.getCurrKey().getValue()).getMemento().restoreState(iter.getCurrVal());
				}
			}
			
		};
	}
	
	public static Effect createEffect(LoadSaveObject loadedEffect) {
		return effectLibrary.get(loadedEffect.get("name"));
	}

}
